﻿using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;

namespace AT.IBMS.Framework.Tools
{

    public static class HttpTool
    {

        /// <summary>
        /// 根据后缀名获取mime类型。
        /// </summary>
        /// <param name="t"></param>
        /// <param name="ext"></param>
        /// <returns></returns>
        public static string GetMimeType(this Tool t, string ext)
        {

            string result;

            if (string.IsNullOrWhiteSpace(ext))
            {
                throw new ArgumentNullException("ext");
            }

            //去掉后缀名的点。
            if (ext.IndexOf(".") != -1)
            {
                ext = ext.Replace(".", "");
            }

            switch (ext)
            {

                case "apk":
                    result = "application/vnd.android.package-archive";
                    break;
                case "3gp":
                    result = "video/3gpp";
                    break;
                case "ai":
                    result = "application/postscript";
                    break;
                case "aif":
                case "aifc":
                case "aiff":
                    result = "audio/x-aiff";
                    break;
                case "asc":
                    result = "text/plain";
                    break;
                case "atom":
                    result = "application/atom+xml";
                    break;
                case "au":
                    result = "audio/basic";
                    break;
                case "avi":
                    result = "video/x-msvideo";
                    break;
                case "bcpio":
                    result = "application/x-bcpio";
                    break;
                case "bin":
                    result = "application/octet-stream";
                    break;
                case "bmp":
                    result = "image/bmp";
                    break;
                case "cdf":
                    result = "application/x-netcdf";
                    break;
                case "cgm":
                    result = "image/cgm";
                    break;
                case "class":
                    result = "application/octet-stream";
                    break;
                case "cpio":
                    result = "application/x-cpio";
                    break;
                case "cpt":
                    result = "application/mac-compactpro";
                    break;
                case "csh":
                    result = "application/x-csh";
                    break;
                case "css":
                    result = "text/css";
                    break;
                case "dcr":
                    result = "application/x-director";
                    break;
                case "dif":
                    result = "video/x-dv";
                    break;
                case "dir":
                    result = "application/x-director";
                    break;
                case "djv":
                case "djvu":
                    result = "image/vnd.djvu";
                    break;
                case "dll":
                case "dmg":
                case "dms":
                    result = "application/octet-stream";
                    break;
                case "doc":
                    result = "application/msword";
                    break;
                case "dtd":
                    result = "application/xml-dtd";
                    break;
                case "dv":
                    result = "video/x-dv";
                    break;
                case "dvi":
                    result = "application/x-dvi";
                    break;
                case "dxr":
                    result = "application/x-director";
                    break;
                case "eps":
                    result = "application/postscript";
                    break;
                case "etx":
                    result = "text/x-setext";
                    break;
                case "exe":
                    result = "application/octet-stream";
                    break;
                case "ez":
                    result = "application/andrew-inset";
                    break;
                case "flv":
                    result = "video/x-flv";
                    break;
                case "gif":
                    result = "image/gif";
                    break;
                case "gram":
                    result = "application/srgs";
                    break;
                case "grxml":
                    result = "application/srgs+xml";
                    break;
                case "gtar":
                    result = "application/x-gtar";
                    break;
                case "gz":
                    result = "application/x-gzip";
                    break;
                case "hdf":
                    result = "application/x-hdf";
                    break;
                case "hqx":
                    result = "application/mac-binhex40";
                    break;
                case "htm":
                case "html":
                    result = "text/html";
                    break;
                case "ice":
                    result = "x-conference/x-cooltalk";
                    break;
                case "ico":
                    result = "image/x-icon";
                    break;
                case "ics":
                    result = "text/calendar";
                    break;
                case "ief":
                    result = "image/ief";
                    break;
                case "ifb":
                    result = "text/calendar";
                    break;
                case "iges":
                    result = "model/iges";
                    break;
                case "igs":
                    result = "model/iges";
                    break;
                case "jnlp":
                    result = "application/x-java-jnlp-file";
                    break;
                case "jp2":
                    result = "image/jp2";
                    break;
                case "jpe":
                case "jpeg":
                case "jpg":
                    result = "image/jpeg";
                    break;
                case "js":
                    result = "application/x-javascript";
                    break;
                case "kar":
                    result = "audio/midi";
                    break;
                case "latex":
                    result = "application/x-latex";
                    break;
                case "lha":
                case "lzh":
                    result = "application/octet-stream";
                    break;
                case "m3u":
                    result = "audio/x-mpegurl";
                    break;
                case "m4a":
                case "m4p":
                    result = "audio/mp4a-latm";
                    break;
                case "m4u":
                    result = "video/vnd.mpegurl";
                    break;
                case "m4v":
                    result = "video/x-m4v";
                    break;
                case "mac":
                    result = "image/x-macpaint";
                    break;
                case "man":
                    result = "application/x-troff-man";
                    break;
                case "mathml":
                    result = "application/mathml+xml";
                    break;
                case "me":
                    result = "application/x-troff-me";
                    break;
                case "mesh":
                    result = "model/mesh";
                    break;
                case "mid":
                case "midi":
                    result = "audio/midi";
                    break;
                case "mif":
                    result = "application/vnd.mif";
                    break;
                case "mov":
                    result = "video/quicktime";
                    break;
                case "movie":
                    result = "video/x-sgi-movie";
                    break;
                case "mp2":
                case "mp3":
                    result = "audio/mpeg";
                    break;
                case "mp4":
                    result = "video/mp4";
                    break;
                case "mpe":
                case "mpeg":
                case "mpg":
                case "mpga":
                    result = "audio/mpeg";
                    break;
                case "ms":
                    result = "application/x-troff-ms";
                    break;
                case "msh":
                    result = "model/mesh";
                    break;
                case "mxu":
                    result = "video/vnd.mpegurl";
                    break;
                case "nc":
                    result = "application/x-netcdf";
                    break;
                case "oda":
                    result = "application/oda";
                    break;
                case "ogg":
                    result = "application/ogg";
                    break;
                case "ogv":
                    result = "video/ogv";
                    break;
                case "pbm":
                    result = "image/x-portable-bitmap";
                    break;
                case "pct":
                    result = "image/pict";
                    break;
                case "pdb":
                    result = "chemical/x-pdb";
                    break;
                case "pdf":
                    result = "application/pdf";
                    break;
                case "pgm":
                    result = "image/x-portable-graymap";
                    break;
                case "pgn":
                    result = "application/x-chess-pgn";
                    break;
                case "pic":
                case "pict":
                    result = "image/pict";
                    break;
                case "png":
                    result = "image/png";
                    break;
                case "pnm":
                    result = "image/x-portable-anymap";
                    break;
                case "pnt":
                case "pntg":
                    result = "image/x-macpaint";
                    break;
                case "ppm":
                    result = "image/x-portable-pixmap";
                    break;
                case "ppt":
                    result = "application/vnd.ms-powerpoint";
                    break;
                case "ps":
                    result = "application/postscript";
                    break;
                case "qt":
                case "qti":
                case "qtif":
                    result = "image/x-quicktime";
                    break;
                case "ra":
                case "ram":
                    result = "audio/x-pn-realaudio";
                    break;
                case "ras":
                    result = "image/x-cmu-raster";
                    break;
                case "rdf":
                    result = "application/rdf+xml";
                    break;
                case "rgb":
                    result = "image/x-rgb";
                    break;
                case "rm":
                    result = "application/vnd.rn-realmedia";
                    break;
                case "roff":
                    result = "application/x-troff";
                    break;
                case "rtf":
                    result = "text/rtf";
                    break;
                case "rtx":
                    result = "text/richtext";
                    break;
                case "sgm":
                case "sgml":
                    result = "text/sgml";
                    break;
                case "sh":
                    result = "application/x-sh";
                    break;
                case "shar":
                    result = "application/x-shar";
                    break;
                case "silo":
                    result = "model/mesh";
                    break;
                case "sit":
                    result = "application/x-stuffit";
                    break;
                case "skd":
                case "skm":
                case "skp":
                case "skt":
                    result = "application/x-koan";
                    break;
                case "smi":
                case "smil":
                    result = "application/smil";
                    break;
                case "snd":
                    result = "audio/basic";
                    break;
                case "so":
                    result = "application/octet-stream";
                    break;
                case "spl":
                    result = "application/x-futuresplash";
                    break;
                case "src":
                    result = "application/x-wais-source";
                    break;
                case "sv4cpio":
                    result = "application/x-sv4cpio";
                    break;
                case "sv4crc":
                    result = "application/x-sv4crc";
                    break;
                case "svg":
                    result = "image/svg+xml";
                    break;
                case "swf":
                    result = "application/x-shockwave-flash";
                    break;
                case "t":
                    result = "application/x-troff";
                    break;
                case "tar":
                    result = "application/x-tar";
                    break;
                case "tcl":
                    result = "application/x-tcl";
                    break;
                case "tex":
                    result = "application/x-tex";
                    break;
                case "texi":
                case "texinfo":
                    result = "application/x-texinfo";
                    break;
                case "tif":
                case "tiff":
                    result = "image/tiff";
                    break;
                case "tr":
                    result = "application/x-troff";
                    break;
                case "tsv":
                    result = "text/tab-separated-values";
                    break;
                case "ustar":
                    result = "application/x-ustar";
                    break;
                case "vcd":
                    result = "application/x-cdlink";
                    break;
                case "vrml":
                    result = "model/vrml";
                    break;
                case "vxml":
                    result = "application/voicexml+xml";
                    break;
                case "wav":
                    result = "audio/x-wav";
                    break;
                case "wbmp":
                    result = "image/vnd.wap.wbmp";
                    break;
                case "wbxml":
                    result = "application/vnd.wap.wbxml";
                    break;
                case "webm":
                    result = "video/webm";
                    break;
                case "wml":
                    result = "text/vnd.wap.wml";
                    break;
                case "wmlc":
                    result = "application/vnd.wap.wmlc";
                    break;
                case "wmls":
                    result = "text/vnd.wap.wmlscript";
                    break;
                case "wmlsc":
                    result = "application/vnd.wap.wmlscriptc";
                    break;
                case "wmv":
                    result = "video/x-ms-wmv";
                    break;
                case "wrl":
                    result = "model/vrml";
                    break;
                case "xbm":
                    result = "image/x-xbitmap";
                    break;
                case "xht":
                case "xhtml":
                    result = "application/xhtml+xml";
                    break;
                case "xls":
                    result = "application/vnd.ms-excel";
                    break;
                case "xml":
                    result = "application/xml";
                    break;
                case "xpm":
                    result = "image/x-xpixmap";
                    break;
                case "xsl":
                    result = "application/xml";
                    break;
                case "xslt":
                    result = "application/xslt+xml";
                    break;
                case "xul":
                    result = "application/vnd.mozilla.xul+xml";
                    break;
                case "xwd":
                    result = "image/x-xwindowdump";
                    break;
                case "xyz":
                    result = "chemical/x-xyz";
                    break;
                case "zip":
                    result = "application/zip";
                    break;
                case "txt":
                default:
                    result = "text/plain";
                    break;
            }

            return result;

        }

        #region Get

        public static string HttpGetRequest(this Tool t, string url)
        {

            string returnData;

            HttpGetRequest(t, url, out returnData);

            return returnData;
        }

        public static WebHeaderCollection HttpGetRequest(this Tool t, string url, out string returnData)
        {

            StreamReader reader;
            MemoryStream memoryStream;
            WebHeaderCollection headers;

            using (memoryStream = new MemoryStream())
            {
                headers = HttpGetRequest(t, url, memoryStream);
                memoryStream.Position = 0;

                using (reader = new StreamReader(memoryStream))
                {

                    returnData = reader.ReadToEnd();
                }

            }

            return headers;

        }

        public static WebHeaderCollection HttpGetRequest(this Tool t, string url, Stream returnData)
        {

            HttpWebRequest request;
            HttpWebResponse response;
            Stream responseStream;
            WebHeaderCollection headers;
            int bytesRead;
            byte[] buffer;

            if (string.IsNullOrWhiteSpace(url))
            {
                throw new ArgumentNullException("url");
            }

            if (returnData == null)
            {
                throw new ArgumentNullException("returnData");
            }

            headers = new WebHeaderCollection();
            request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "GET";

            using (response = (HttpWebResponse)request.GetResponse())
            {

                using (responseStream = response.GetResponseStream())
                {

                    buffer = new byte[1024];

                    while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        returnData.Write(buffer, 0, bytesRead);
                    }

                }

                headers.Add(response.Headers);

            }

            return headers;

        }

        #endregion

        #region Post文本

        public static string HttpPostRequest(this Tool t, string url, string data)
        {
            string returnData;

            HttpPostRequest(t, url, data, out returnData);

            return returnData;
        }

        public static WebHeaderCollection HttpPostRequest(this Tool t, string url, string data, out string returnData)
        {
            StreamReader reader;
            MemoryStream memoryStream;
            WebHeaderCollection headers;

            using (memoryStream = new MemoryStream())
            {
                headers = HttpPostRequest(t, url, data, memoryStream);
                memoryStream.Position = 0;

                using (reader = new StreamReader(memoryStream))
                {
                    returnData = reader.ReadToEnd();
                }

            }

            return headers;
        }

        public static WebHeaderCollection HttpPostRequest(this Tool t, string url, string data, Stream returnData)
        {

            HttpWebRequest request;
            HttpWebResponse response;
            Stream responseStream;
            StreamWriter writer;
            WebHeaderCollection headers;
            int bytesRead;
            byte[] buffer;

            if (string.IsNullOrWhiteSpace(url))
            {
                throw new ArgumentNullException("url");
            }

            if (returnData == null)
            {
                throw new ArgumentNullException("returnData");
            }

            headers = new WebHeaderCollection();
            request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "POST";

            using (writer = new StreamWriter(request.GetRequestStream()))
            {
                writer.Write(data);
                writer.Flush();
            }

            using (response = (HttpWebResponse)request.GetResponse())
            {

                using (responseStream = response.GetResponseStream())
                {
                    buffer = new byte[1024];

                    while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        returnData.Write(buffer, 0, bytesRead);
                    }
                }

                headers.Add(response.Headers);

            }

            return headers;
        }

        #endregion

        #region Post数据流

        public static string HttpPostRequest(this Tool t, string url, string filePath, string paramName, string contentType, NameValueCollection nvc = null)
        {
            string returnData;

            HttpPostRequest(t, url, filePath, out returnData, paramName, contentType, nvc);

            return returnData;
        }

        public static WebHeaderCollection HttpPostRequest(this Tool t, string url, string filePath, out string returnData, string paramName, string contentType, NameValueCollection nvc = null)
        {
            StreamReader reader;
            MemoryStream memoryStream;
            WebHeaderCollection headers;

            using (memoryStream = new MemoryStream())
            {
                headers = HttpPostRequest(t, url, filePath, memoryStream, paramName, contentType, nvc);
                memoryStream.Position = 0;

                using (reader = new StreamReader(memoryStream))
                {
                    returnData = reader.ReadToEnd();
                }

            }

            return headers;
        }

        public static WebHeaderCollection HttpPostRequest(this Tool t, string url, string filePath, Stream returnData, string paramName, string contentType, NameValueCollection nvc = null)
        {

            string boundary;
            byte[] boundarybytes;
            HttpWebRequest request;
            Stream requestStream;
            string formdataTemplate;
            string headerTemplate;
            string header;
            byte[] headerbytes;
            FileStream fileStream;
            byte[] buffer;
            int bytesRead;
            byte[] trailer;
            WebResponse response;
            Stream responseStream;
            WebHeaderCollection headers;

            headers = new WebHeaderCollection();
            boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
            formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
            headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";

            request = (HttpWebRequest)WebRequest.Create(url);
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            request.Method = "POST";
            request.KeepAlive = true;
            request.Credentials = CredentialCache.DefaultCredentials;

            using (requestStream = request.GetRequestStream())
            {
                if (nvc != null)
                {

                    foreach (string key in nvc.Keys)
                    {
                        requestStream.Write(boundarybytes, 0, boundarybytes.Length);
                        string formitem = string.Format(formdataTemplate, key, nvc[key]);
                        byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                        requestStream.Write(formitembytes, 0, formitembytes.Length);
                    }

                }

                requestStream.Write(boundarybytes, 0, boundarybytes.Length);
                header = string.Format(headerTemplate, paramName, filePath, contentType);
                headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
                requestStream.Write(headerbytes, 0, headerbytes.Length);

                using (fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    buffer = new byte[1024];
                    bytesRead = 0;

                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        requestStream.Write(buffer, 0, bytesRead);
                    }

                }

                trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                requestStream.Write(trailer, 0, trailer.Length);

            }

            using (response = request.GetResponse())
            {
                using (responseStream = response.GetResponseStream())
                {
                    buffer = new byte[1024];
                    bytesRead = 0;

                    while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        returnData.Write(buffer, 0, bytesRead);
                    }
                }

                headers.Add(response.Headers);
            }

            return headers;

        }

        #endregion

    }

}
